package com.websocket.endpoint;

import org.springframework.stereotype.Component;

import javax.sound.midi.Track;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * @program: RuoYi-Cloud-master
 * @ClassName IntelligentCustomerEndpoint
 * @description:
 * @author:
 * @create: 2023-11-22 20:46
 * @Version 1.0
 **/

@ServerEndpoint("/websocket/customer/{loginName}")//
@Component
public class IntelligentCustomerEndpoint {
    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static final AtomicInteger onlineNum = new AtomicInteger(0);
    //concurrent包的线程安全Set，用来存放每个客户端对应的Session对象。
    private static final Set<IntelligentCustomerEndpoint> connectionsCustomer = new CopyOnWriteArraySet<>();

    private String loginName;
    public Session session;

    private IntelligentCustomerServiceEndpoint pair = null;//null 空闲的状态
    public IntelligentCustomerServiceEndpoint getCSPair() {
        return pair;
    }

    public void setCSPair(IntelligentCustomerServiceEndpoint pair) {
        this.pair = pair;
    }
    /**
     * 当有ws 客户端连接进来，调用的方法
     * @param session
     */
    @OnOpen //创建一个websocket 就会执行OnOpen
    public void start(Session session, @PathParam("loginName") String loginName) throws IOException {
        this.loginName = loginName;
        this.session = session;
        System.out.println("this:" + this);
        connectionsCustomer.add(this);

        onlineNum.incrementAndGet();//i++  ++i

        String msg = String.format("欢迎 %s(%s)加入，当前在线人数 %d",loginName,session.toString(),onlineNum.get());
        System.out.println(msg);
        this.session.getBasicRemote().sendText(msg);//给自己发欢迎消息
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose //ws.close
    public void end(Session session,@PathParam("loginName") String loginName) throws IOException {
        connectionsCustomer.remove(this);

        this.getCSPair().session.getBasicRemote().sendText(loginName + ":" + "退出");
        this.setCSPair(null);//断开与客服的关联

        onlineNum.decrementAndGet();//i--
        String msg = String.format("%s(%s) 退出，当前在线人数 %d",loginName,session.toString(),onlineNum.get());
        System.out.println(msg);
        this.session.getBasicRemote().sendText(msg);//给自己发离开的消息
    }

    /**
     * 接收到消息的监听方法
     * @param message
     */
    @OnMessage //ws.send
    public void incoming(Session session, String message, @PathParam("loginName") String loginName) throws IOException {
        String msg = String.format("发送者%s(%s)发送消息： %s",loginName,session.toString(),message);
        System.out.println(msg);

        //智能客服
        if (message.equals("转人工")) {
            Set<IntelligentCustomerServiceEndpoint> connectionsCustomerService =
                    IntelligentCustomerServiceEndpoint.connectionsCustomerService;
            boolean findCS = false;
            for (IntelligentCustomerServiceEndpoint cs:connectionsCustomerService){
                if(cs.getPair()==null){
                    cs.setPair(this);////建立用户与客服的关联
                    this.setCSPair(cs);
                    findCS = true;
                    break;
                }
            }
            if(findCS){//找到空闲的客服
                this.getCSPair().session.getBasicRemote().sendText(loginName + " 请求服务");
                this.session.getBasicRemote().sendText("客服:" + this.getCSPair().loginName + "为您服务");//
            }else{
                this.session.getBasicRemote().sendText("智能客服:" + "所有的客服都忙着，请稍等");//
            }
        }else{
            if(this.getCSPair()!=null){//找到空闲的客服
                this.getCSPair().session.getBasicRemote().sendText(loginName + ":" + message);
                this.session.getBasicRemote().sendText(this.loginName +":"+ message);//给自己发
            }else{
                this.session.getBasicRemote().sendText("智能客服:" + "======正在ES搜索");//
            }
        }
    }

    @OnError
    public void onError(Throwable t) throws Throwable {
        System.out.println("onError");
        t.printStackTrace();
    }
}
